fix: paginate blog sitemap to include all posts - #1293
Merged
Conversation
Ghost's Content API silently caps a single response at 100 posts even when limit=all is requested, so the blog sitemap dropped every post beyond the first 100 (129 posts existed, only 100 were listed). Add getAllPosts() which pages through Ghost with the maximum page size, following meta.pagination.next until exhausted, and use it in the sitemap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The blog sitemap (
/blog/sitemap.xml) only listed 100 posts even though 129 exist. The route requestedlimit=allfrom Ghost, but Ghost's Content API silently caps a single response at 100 posts ("limit":100,"pages":2in the pagination metadata). Because the sitemap did a single request with no pagination, every post beyond the first 100 was dropped from search-engine indexing, and the gap grows as more posts are published.Lessons learnt
limit=allis not honoured as "everything in one response" — it is capped at 100 per page. To fetch a complete collection you must paginate and followmeta.pagination.nextuntil it isnull.meta.pagination.total, not the number of<loc>entries returned by a single call — the two can silently diverge at the 100 boundary.fetch.Summary
getAllPosts()tosrc/lib/blog/client.ts— pages through Ghost with the maximum page size (100), followingmeta.pagination.nextuntil exhausted, with a guard against a non-advancingnextto avoid infinite loops.getAllPosts()insrc/routes/blog/sitemap.xml/+server.tsinstead of the singlegetPosts({ limit: 'all' })call.src/lib/blog/client.test.tscovering multi-page (>100), max page size, and single-page cases.